package cn.ipanel.bigdata

import cn.ipanel.bigdata.boot.config.Configuration
import cn.ipanel.bigdata.boot.source.genre.Hive
import cn.ipanel.bigdata.comm.Parameter
import cn.ipanel.bigdata.utils.Util.strToI

/**
 * Author: lzz
 * Date: 2022/3/24 19:09
 */
package object dw {

  lazy val TABLE: Seq[Hive] = ods.Tables ++ dwd.Tables ++ dwm.Tables
  final lazy val SUM_REGION_SERVERS: Int = strToI(Configuration.getParam(Parameter.SUM_REGION_SERVERS), 12)

  trait Const {

    final lazy val NONE       : String = "None"
    final lazy val INT1       : Int = 1
    final lazy val INT0       : Int = 0
    final lazy val INTX       : Int = -1
    final lazy val LONG0      : Long = 0L
    final lazy val DOUBLE0    : Double = 0
    final lazy val EMPTY_MAP  : Map[String, String] = Map()
    final lazy val DEFAULT_ALL: String = "ALL"

    final lazy val STORAGE_FORMATTER_TEXTFILE : String = "textfile"
    final lazy val STORAGE_FORMATTER_ORC      : String = "orc"
    final lazy val STORAGE_FORMATTER_PARQUET  : String = "parquet"
    final lazy val STORAGE_FORMATTER_DEFAULT  : String = STORAGE_FORMATTER_ORC

    def storageFormatter: String = STORAGE_FORMATTER_DEFAULT
    def splitBucketsNums: Int = 4
    def dataRowFormatter: String = "'\001'"
    def dataMapFormatter: String = "':'"
  }

  trait BaseColumns {
    final val F_DATE          : String = "f_date"                   // yyyyMMdd 格式的日期
    final val F_PERIOD_TIME   : String = "f_period_time"            // 周期时间，如：年 2023 -> 23（2位）,
    //            季 20231 -> 231（3位），
    //            月 202301 -> 2301（4位），
    //            周 23年第一周 -> 23001（5位，可以4位，月只占用[2301, 2312]），
    //            天 20230101 ->230101（6位），
    //            小时 2023年1月1日12时 -> 23010112（8位）
    // 由于Integer范围是[-2147483648, 2147483647]（10位）
    // 这种方式不支持到分钟的粒度，不过可以使用一个Integer，用 bit 位移的方式来实现，如：
    // 高8位表示类型，低24位表示值，不过对于使用者来说很不方便，不好读
    final val F_REGION        : String = "f_region"                 // （市）区域ID
    final val F_DEVICE_COUNT  : String = "f_device_count"           // 设备数
  }

  trait AppColumns {
    final val F_APP_ID        : String = "f_app_id"                 // 应用包名
    final val F_APP_VERSION   : String = "f_app_version"            // 应用版本号
  }

  trait DetailColumns {
    final val F_DEVICE_ID     : String = "f_device_id"              // 设备id，默认是mac
    final val F_CREATE_DATE   : String = "f_create_date"            // 创建日期
    final val F_CREATE_TIME   : String = "f_create_time"            // 创建时间
    final val F_UPDATE_DATE  : String = "f_update_date"             // 更新日期
    final val F_UPDATE_TIME  : String = "f_update_time"             // 更新时间
  }

  abstract class AbsDwHive(dbName: String, tbName: String)
          extends Hive(dbName, tbName) with Const {

    def createTable: AbsDwTable
    /**
     * 除去基本字段外，表的其他字段，注意顺序必须跟 Hive 表定义的顺序一致
     * @return
     */
    def extraColumnNames: Seq[String] = Seq()
    def extraColumnBuild: String = ""
  }

  abstract class AbsDwTable()
          extends Const
            with Serializable

  /**
   * 兼容scala2.10，只支持22个字段的case class问题
   */
  abstract class AbsExtProduct extends Product with Serializable {
    lazy val _d: Array[Any] = toParam
    def toParam: Array[Any]
    override def productElement(n: Int): Any = _d(n)
    override def productArity: Int = _d.length
    override def canEqual(that: Any): Boolean = _d.contains(that)
  }
}